﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using XD.Core;

namespace GCDHelper
{
    /// <summary>
    /// gcd解析器
    /// </summary>
    public class GcdHelper
    {
        /// <summary>
        /// 图层数目
        /// </summary>
        public int LayerNumber
        {
            get { return this.layers.Count; }
        }

        /// <summary>
        /// 图层
        /// </summary>
        public List<GcdLayer> Layers
        {
            get { return this.layers; }
        }
        private List<GcdLayer> layers = null;

        /// <summary>
        /// 解析文件
        /// </summary>
        /// <param name="file"></param>
        public void Read(string file)
        {
            this.layers = new List<GcdLayer>();

            try
            {
                string line = string.Empty;//单行文本
                string tempValue = string.Empty;//值文本，辅助数据转换
                using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
                {
                    Encoding encoding = GetTxtFileEncoding.GetEncoding(fs);
                    using (StreamReader sr = new StreamReader(fs, encoding))
                    {   
                        //根节点
                        sr.ReadLine();//SchemeBegin

                        //图层数
                        tempValue = GetValue(sr.ReadLine());//LayerNumber
                        if (string.IsNullOrEmpty(tempValue))
                        {
                            return;
                        }
                        int lyCount = 0;
                        if (int.TryParse(tempValue, out lyCount) == false)
                        {
                            return;
                        }
                        if (lyCount < 1)
                        {
                            return;
                        }

                        //读取图层
                        for (int i = 0; i < lyCount; i++)
                        {
                            try
                            {
                                sr.ReadLine();//LayerBegin

                                #region 图层信息

                                //图层信息
                                GcdLayer ly = new GcdLayer()
                                {
                                    LayerName = GetValue(sr.ReadLine()),
                                    LayerShapeType = (EnumGcdLayerShapeType)(int.Parse(GetValue(sr.ReadLine()))),
                                    LayerDatasetContainer = GetValue(sr.ReadLine()),
                                    LayerSymbolItem = GetValue(sr.ReadLine()),
                                    LayerRestrictionCondition = GetValue(sr.ReadLine()),
                                    LayerDescription = GetValue(sr.ReadLine())
                                };

                                #endregion

                                #region 字段信息

                                sr.ReadLine();//TableBegin

                                //字段数
                                tempValue = GetValue(sr.ReadLine());//ItemNumber
                                if (string.IsNullOrEmpty(tempValue))
                                {
                                    return;
                                }
                                int itemCount = 0;
                                if (int.TryParse(tempValue, out itemCount) == false)
                                {
                                    return;
                                }

                                //字段
                                for (int j = 0; j < itemCount; j++)
                                {
                                    try
                                    {
                                        sr.ReadLine();//ItemBegin

                                        GcdItem item = new GcdItem()
                                        {
                                            ItemName = GetValue(sr.ReadLine()),
                                            ItemType = (EnumGcdItemType)(int.Parse(GetValue(sr.ReadLine()))),
                                            ItemWidth = int.Parse(GetValue(sr.ReadLine())),
                                            ItemPrecition = int.Parse(GetValue(sr.ReadLine())),
                                            ItemIsNullable = bool.Parse(GetValue(sr.ReadLine())),
                                            ItemDomain = GetValue(sr.ReadLine()),
                                            ItemRestrictionCondition = GetValue(sr.ReadLine()),
                                            ItemRealTimeShow = bool.Parse(GetValue(sr.ReadLine())),
                                            ItemDescription = GetValue(sr.ReadLine())
                                        };

                                        sr.ReadLine();//ItemEnd

                                        if (ly.Items == null)
                                        {
                                            ly.Items = new List<GcdItem>();
                                        }
                                        ly.Items.Add(item);
                                    }
                                    catch (Exception ex)
                                    {
                                        Exception e = new Exception("error item index : " + j, ex);
                                        throw e;
                                    }
                                }

                                sr.ReadLine();//TableEnd

                                #endregion

                                #region 要素信息

                                sr.ReadLine();//FeatureClassBegin

                                //字段数
                                tempValue = GetValue(sr.ReadLine());//FeatureNumber
                                if (string.IsNullOrEmpty(tempValue))
                                {
                                    return;
                                }
                                int featureCount = 0;
                                if (int.TryParse(tempValue, out featureCount) == false)
                                {
                                    return;
                                }

                                //字段
                                for (int j = 0; j < featureCount; j++)
                                {                                    
                                    try
                                    {
                                        sr.ReadLine();//FeatureBegin

                                        GcdFeature feature = new GcdFeature()
                                        {
                                            Code = GetValue(sr.ReadLine()),
                                            FeatureGeometryType = (EnumGcdFeatureGeometryType)(int.Parse(GetValue(sr.ReadLine()))),
                                            IsElevation = bool.Parse(GetValue(sr.ReadLine())),
                                            FeatureStyle = GetValue(sr.ReadLine()),
                                            FeatureDirectional = bool.Parse(GetValue(sr.ReadLine())),
                                            FeatureMinSize = int.Parse(GetValue(sr.ReadLine())),
                                            FeatureDescription = GetValue(sr.ReadLine())
                                        };

                                        sr.ReadLine();//FeatureEnd

                                        if (ly.Features == null)
                                        {
                                            ly.Features = new List<GcdFeature>();
                                        }
                                        ly.Features.Add(feature);
                                    }
                                    catch (Exception ex)
                                    {
                                        Exception e = new Exception("error feature index : " + j, ex);
                                        throw e;
                                    }
                                }

                                sr.ReadLine();//FeatureClassEnd

                                #endregion

                                sr.ReadLine();//LayerEnd

                                this.layers.Add(ly);
                            }
                            catch (Exception ex)
                            {
                                Exception e = new Exception("error layer index : " + i, ex);
                                throw e;
                            }
                        }

                        sr.ReadLine();//SchemeEnd
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 获取值
        /// line格式：<LayerNumber = 34>
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        private string GetValue(string line)
        {
            return line.Substring(line.IndexOf("=") + 1, line.LastIndexOf(">") - line.IndexOf("=") - 1).Trim();
        }
    }   
}
